package com.lhy.skywalking.order.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lhy.skywalking.common.domain.AjaxResult;
import com.lhy.skywalking.order.dto.OrderDTO;
import com.lhy.skywalking.order.entity.Order;
import com.lhy.skywalking.order.mapper.OrderMapper;
import com.lhy.skywalking.order.service.OrderService;
import com.lhy.skywalking.product.ProductFeignService;
import com.lhy.skywalking.product.dto.ProductDTO;
import com.lhy.skywalking.user.UserFeignService;
import com.lhy.skywalking.user.dto.UserDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.apache.skywalking.apm.toolkit.trace.SupplierWrapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

@Slf4j
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {



    @Autowired
    private UserFeignService userFeignService;

    @Autowired
    private ProductFeignService productFeignService;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Override
    public OrderDTO datailById(long id) {
        Order order = super.getById(id);
        if (order != null) {
            OrderDTO dto = new OrderDTO();
            BeanUtils.copyProperties(order, dto);

            // 查找支付用户
//            AjaxResult payUser = userFeignService.findById(order.getPayerUserId());
//            dto.setPayUser(JSON.parseObject(JSON.toJSONString(payUser.get("data")), UserDTO.class));
//
//            // 查找收款用户
//            AjaxResult receiverUser = userFeignService.findById(order.getReceiveUserId());
//            dto.setReceiverUser(JSON.parseObject(JSON.toJSONString(receiverUser.get("data")), UserDTO.class));
//
//            // 查找商品
//            AjaxResult product = productFeignService.findById(order.getProductId());
//            dto.setProduct(JSON.parseObject(JSON.toJSONString(product.get("data")), ProductDTO.class));

            // 异步 使用SupplierWrapper.of 应用链路追踪
            CompletableFuture<AjaxResult> payUserCompletableFuture = CompletableFuture.supplyAsync(SupplierWrapper.of(() -> userFeignService.findById(order.getPayerUserId())));
            CompletableFuture<AjaxResult> receiverUserCompletableFuture = CompletableFuture.supplyAsync(SupplierWrapper.of(() -> userFeignService.findById(order.getReceiveUserId())));
            CompletableFuture<AjaxResult> productCompletableFuture = CompletableFuture.supplyAsync(SupplierWrapper.of(() -> productFeignService.findById(order.getProductId())));

            CompletableFuture<Void> voidCompletableFuture = CompletableFuture.allOf(payUserCompletableFuture, receiverUserCompletableFuture, productCompletableFuture);


            while (!voidCompletableFuture.isDone()) {
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            try {
                dto.setPayUser(JSON.parseObject(JSON.toJSONString(payUserCompletableFuture.get().get("data")), UserDTO.class));
                dto.setReceiverUser(JSON.parseObject(JSON.toJSONString(receiverUserCompletableFuture.get().get("data")), UserDTO.class));
                dto.setProduct(JSON.parseObject(JSON.toJSONString(productCompletableFuture.get().get("data")), ProductDTO.class));
            } catch (InterruptedException | ExecutionException e) {
                throw new RuntimeException(e);
            }
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            // 发送mq消息
            SendResult result = rocketMQTemplate.syncSend("ORDER:DETALIS", dto);
            log.info("[MQ Result] 发送状态:{}", result.getSendStatus());
            log.info("[MQ Result] 消息id:{}", result.getMsgId());
            log.info("[MQ Result] 消息队列:{}", result.getMessageQueue().getQueueId());
            return dto;
        }
        return null;
    }
}
